#!/usr/bin/env python

# Copyright (c) 2011 - 2012 Tony Bai <bigwhite.cn@gmail.com>
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
# http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import sys
import os
import shutil
import command
import config
import env
import errnos

from ftplib import FTP

SETUP_CFG_FILE = "./setup.cfg"

def __pack_init():
  c = config.load_config(SETUP_CFG_FILE)
  return c.distribution, c.source

def __build_source(build_home, url, cmode, binary_prefix):
  command.execute('mkdir -p ' + build_home + '/.build')
  os.chdir(build_home + '/.build')
  print "Create dir [.build] OK!"

  command.execute('svn export ' + url)
  print "Export [" + url + "] OK!"

  source_home = build_home + '/.build/' + url[url.rindex("/")+1:]
  os.chdir(source_home)
  print "Cd " + source_home

  command.execute('buildc config-make')
  print "Config Make.rules OK!"

  command.execute('make CMODE=' + cmode)
  print "Make Ok"

  command.execute('cp ' + binary_prefix + '* ' + build_home + '/src/app')
  print "Copy binary file to [" + build_home + '/src/app]' + " Ok!"

  os.chdir(build_home)
  print "Cd " + build_home

  command.execute('rm -fr ' + build_home + '/.build')
  print 'Del [.build] OK!'

  print 'Build source [' + url + '] OK!'

def __make_package(build_home, distribution, cmode):
  os.chdir(build_home)

  command.execute('mkdir -p ' + build_home + '/.package')
  print "Create dir [.package] OK!"

  target_prefix = distribution["packname"] + \
           '-' + distribution["version"] + \
           '-' + env.cpu() + \
           '-' + env.os() + \
           '-' + cmode[:2] + 'bit'

  if sys.version_info[0] == 2 and sys.version_info[1] < 6:
    shutil.copytree(build_home + '/src', build_home + '/.package/' + target_prefix)
  else:
    shutil.copytree(build_home + '/src', build_home + '/.package/' + target_prefix, 
                    ignore = shutil.ignore_patterns('*.pyc', '.svn'))

  os.chdir(build_home + '/.package')
  print "Cd " + build_home + '/.package'

  command.execute('tar cvf ' + target_prefix + '.tar ' + target_prefix)
  print 'Generate ' + target_prefix + '.tar' + ' OK!'

  command.execute('gzip ' + target_prefix + '.tar')
  print('Zip ' + target_prefix + '.tar' + ' OK!')

  os.chdir(build_home)
  print('Cd ' + build_home)

  command.execute('mv .package/' + target_prefix + '.tar.gz ' + 'distributions')
  command.execute('rm -fr ' + build_home + '/.package')
  print 'Del [.package] OK!'

  print('Make target [' + target_prefix + '.tar.gz] OK!')

def __do_clean(build_home):
  command.execute('rm -fr ' + build_home + '/.build')
  print 'Clean [.build] OK!'
  
  command.execute('rm -fr ' + build_home + '/.package')
  print 'Clean [.package] OK!'

  command.execute('rm -f ' + build_home + '/src/app/*')
  print 'Clean [./src/app] OK!'

  command.execute('rm -f ' + build_home + '/distributions/*.tar.gz')
  print 'Clean [./distributions] OK!'

  print 'Package distribution clean OK!'
  
def __do_pack(build_home, source, distribution, opts):
  url = ''

  __do_clean(build_home)

  if opts.tag != None:
    url = opts.tag
  else:
    url = source["trunk"]
  
  cmode = opts.cmode

  __build_source(build_home, url, cmode, source["binary_prefix"])
  __make_package(build_home, distribution, cmode)

def __do_upload(build_home, distribution, opts):
    target_prefix = distribution["packname"] + \
            '-' + distribution["version"] + \
            '-' + env.cpu() + \
            '-' + env.os() + \
            '-' + opts.cmode[:2] + 'bit'

    os.chdir(build_home + '/distributions')
    print('Cd ' + 'distributions')

    ftp = FTP()

    if opts.port != None:
        ftp.connect(host = opts.host, port = opts.port)
    else:
        ftp.connect(host = opts.host)

    if opts.user != None:
        ftp.login(user = opts.user, passwd = opts.passwd) 
    else:
        ftp.login()

    if opts.dir == None:
        print "Error: no remote dir is given!"
        sys.exit(errnos.errors['args_invalid'])

    ftp.cwd(opts.dir)
    f = file(target_prefix + '.tar.gz', 'r')
    ftp.storbinary("STOR " + target_prefix + '.tar.gz', f)
    f.close()
    ftp.quit()
    ftp.close()

    os.chdir(build_home)
    print 'Upload [' + target_prefix + '.tar.gz] OK!'

def pack_create(buildc_home, opts):
    if opts.project == None:
        print "Error: no project name is given!"
        sys.exit(errnos.errors['args_invalid'])

    if os.path.exists(opts.project):
        print "Error: [" + opts.project + "] has already existed!"
        sys.exit(errnos.errors['file_or_dir_exists'])

    command.execute('mkdir -p ' + opts.project)
    command.execute('cp ' + buildc_home + '/samples/setup.cfg.sample ' + opts.project + '/' + SETUP_CFG_FILE)
    command.execute('mkdir -p ' + opts.project + '/distributions')
    command.execute('mkdir -p ' + opts.project + '/src/app')
    command.execute('cp ' + buildc_home + '/samples/setup.py.sample ' + opts.project + '/src/setup.py')
    command.execute('cp ' + buildc_home + '/samples/layout.cfg.sample ' + opts.project + '/src/layout.cfg')
    command.execute('touch ' + opts.project + '/src/README')
    command.execute('mkdir -p ' + opts.project + '/src/deps')
    command.execute('mkdir -p ' + opts.project + '/src/conf')
    command.execute('mkdir -p ' + opts.project + '/src/others')
    command.execute('mkdir -p ' + opts.project + '/src/scripts')
    command.execute('cp ' + buildc_home + '/samples/deps_check.py.sample ' + opts.project + '/src/scripts/deps_check.py')
    command.execute('cp ' + buildc_home + '/samples/env_gen.py.sample ' + opts.project + '/src/scripts/env_gen.py')
    
    print "Setup project [" + opts.project + "] create OK!"
    sys.exit(0)

def pack_build(opts):
    build_home = os.getcwd()
    distribution, source = __pack_init()
    __do_pack(build_home, source, distribution, opts)
    sys.exit(0)

def pack_clean():
    build_home = os.getcwd()
    __do_clean(build_home)
    sys.exit(0)

def pack_upload(opts):
    build_home = os.getcwd()
    distribution, source = __pack_init()
    __do_upload(build_home, distribution, opts)
    sys.exit(0)
    
if __name__ == '__main__':
    print 'pack'
